<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Custom Ace Editor</title>
    <style>
        #editor {
            width: 100%;
            height: 500px;
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ext-language_tools.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/mode-sql.js"></script>
</head>
<body>
    <div id="editor">
        SELECT
            name,
            age,
            sex
        FROM
        (
            select
            *
            from user
            where a = 1
        )
        WHERE
        aaa = 1
        AND sex > 2</div>
    <script>
        var editor = ace.edit("editor");
        editor.session.setMode("ace/mode/sql");
        editor.setOptions({
            enableBasicAutocompletion: true,
            enableSnippets: true,
            enableLiveAutocompletion: true
        });

        // 获取现有的 SQL FoldMode
        var Range = ace.require("ace/range").Range;
        var SqlMode = ace.require("ace/mode/sql").Mode;
        var BaseFoldMode = ace.require("ace/mode/folding/fold_mode").FoldMode;

        // 自定义 SQL 折叠规则
        var MySqlFoldMode = function() {
            this.foldingStartMarker = /(\bSELECT\b|\()/i;
            this.foldingStopMarker = /(\bFROM\b|\))/i;
        };

        MySqlFoldMode.prototype = Object.create(BaseFoldMode.prototype);
        MySqlFoldMode.prototype.constructor = MySqlFoldMode;

        MySqlFoldMode.prototype.getFoldWidgetRange = function(session, foldStyle, row) {
            var line = session.getLine(row);
            var match = line.match(this.foldingStartMarker);
            if (match) {
                var startColumn = match.index + match[0].length;
                var startRow = row;

                var maxRow = session.getLength();
                var endRow = row;
                var endColumn = line.length;

                while (++row < maxRow) {
                    line = session.getLine(row);
                    if (line.match(this.foldingStopMarker)) {
                        endRow = row;
                        endColumn = line.length;
                        break;
                    }
                }

                if (endRow > startRow) {
                    return new Range(startRow, startColumn, endRow, endColumn);
                }
            }
        };

        // 设置自定义折叠规则
        var sqlMode = new SqlMode();
        sqlMode.foldingRules = new MySqlFoldMode();
        editor.session.setMode(sqlMode);

        editor.session.setFoldStyle("markbegin");
    </script>
</body>
</html>
